#! /bin/sh
# PCP QA Test No. 354
# more serious exercising of record mode in libpcp_gui
#
# Copyright (c) 1995-2002 Silicon Graphics, Inc.  All Rights Reserved.
#
# check-group-include: folio
#

seq=`basename $0`
echo "QA output created by $seq"

# get standard filters
. ./common.product
. ./common.filter
. ./common.check

signal=$PCP_BINADM_DIR/pmsignal
host=`hostname`
status=1	# failure is the default!
trap "cd $here; rm -rf $tmp $tmp.*; exit \$status" 0 1 2 3 15
mkdir $tmp
if [ ! -d $tmp ]
then
    echo "Arrgh, failed to mkdir \"$tmp\""
    ls -ld $tmp
fi
cd $tmp

_build_sed()
{
    echo 's/$/ /' >$tmp.sed
    echo "s/$host/HOST/g" >>$tmp.sed
    $PCP_AWK_PROG <$1 >>$tmp.sed '
BEGIN	{ numpid = 0; pid[""] = 1 }
/pid:/	{ if ($6 == 0) next
	  for (i in pid) {
	    if ($6 == pid[i]) next
	  }
	  numpid++
	  pid[numpid] = $6
	  print "s/ " $6 "\\([^0-9]\\)/ pmlogger-pid-" numpid "\\1/g"
	}'
    echo 's/ $//' >>$tmp.sed
}

# Note on last awk ...
#   In the CI environment we've found that there is non-determinism in
#   the output of the "Log finished ..." line and the preceding blank line,
#   and some other missing blank lines!
#   The cause seems related to atexit() handling and sharing of the stderr
#   stream across multiple processes.  It is not directly related to the
#   purpose of this test, so these lines are filtered out.
#
_filter()
{
    sed <$1 \
	-e "s/$MKTEMP/MKTEMP/" \
	-e "s/$host/HOST/" \
	-e 's/[0-9][^ ]* [kmKM]*bytes/SOME bytes/g' \
	-e 's/[0-9][^ ]* seconds/SOME seconds/g' \
	-e "s/$seq-$$/SEQ-PID/g" \
	-e '/xconfirm: Not found/d' \
	-e '/pmRecordControl/s/Bad file descriptor/Invalid argument/' \
	-e 's/ f_ipc: [0-9][0-9]*/ f_ipc: N/' \
	| sed -f $tmp.sed \
    | _filter_pmlogger_log \
    | sed \
        -e 's/\/[A-Z]*\/tmp/\/tmp/' \
        -e 's/\/[a-z]*\/tmp/\/tmp/' \
    | $PCP_AWK_PROG '
NF == 0			{ next }
/Log finished DATE/	{ next }
			{ print }'
}

_filter_ps()
{
$PCP_AWK_PROG '
NR == 1	{ if ($2 != "PID") {
	    print "PID not in field 2 of ps output!"
	    print
	    exit(1)
	  }
	  if ($8 == "CMD" || $8 == "COMMAND")
	    # Linux-like
	    cmd = 8
	  else if ($11 == "COMMAND")
	    # old-style BSD
	    cmd = 11
	  else {
	    print "CMD (or COMMAND) not in field 8 (or 11) of ps output!"
	    print
	    exit(1)
	  }
	  next
	}
	{ print "ps:",$2,$cmd,$(cmd+1),$(cmd+2),$(cmd+3),$(cmd+4) }'
}

rm -f $seq_full

# NOT the default pmconfirm(1), please
#
cat <<'End-of-File' >$tmp.xconfirm
#!/bin/sh
# generate no output so pmlogger will report the message
exit 0
End-of-File
chmod 755 $tmp.xconfirm
export PCP_XCONFIRM_PROG=$tmp.xconfirm

# real QA test starts here

echo
echo "=== folio name relative to cwd ==="
echo "=== folio name relative to cwd ===" >>$seq_full
echo

$here/src/record foo no-1 1 $host localhost $host localhost 2>&1 >$tmp.out &
sleep 10

# We used to have the temp basename created and left over (this was a bug).
# In fixing the bug we've made this test much harder ...
# typical output from ls looks like
# lZYiOHa.localhost.0
# lZYiOH.localhost.0
# and we need to extract lZYiOH not lZYiOHa
#
MKTEMP=`ls *.localhost.0 \
        | tee -a $seq_full \
	| awk '{ print length($0),$0 }' \
	| sort -n \
	| sed -e 's/^[0-9][0-9]* //' -e 's/\.localhost\.0//' -e 1q`
echo "MKTEMP=$MKTEMP" >>$seq_full
_build_sed $tmp.out
echo "-- $tmp.sed --" >>$seq_full
cat $tmp.sed >>$seq_full
echo "-- $tmp.out --" >>$seq_full
cat $tmp.out >>$seq_full
_filter $tmp.out
echo
echo "pmlogger processes:"
echo "pmlogger processes:" >>$seq_full
ps $PCP_PS_ALL_FLAGS 2>&1 \
| tee -a $seq_full \
| sed -n \
    -e 1p \
    -e '/check .*-g pmlogger/d' \
    -e '/[p]mlogger.*-x/{
s/ -x [0-9][0-9]*/ -x N/
p
}' \
| _filter_ps \
| tee $tmp.tmp \
| sed -f $tmp.sed \
| LC_COLLATE=POSIX sort
pid=`$PCP_AWK_PROG '{ print $2 }' <$tmp.tmp`
if [ -z "$pid" ]
then
    # oops!
    #
    echo "Arrgh, no pmlogger process found ... see $seq.full"
    exit
else
    echo "pmlogger pid: $pid" >>$seq_full
    npmlogger=`echo "$pid" | wc -w | sed -e 's/ //g'`
    if [ "$npmlogger" -ne 1 ]
    then
	echo "Arrgh, expecting 1 pmlogger process found $npmlogger processes ... see $seq.full"
	exit
    fi
    $signal -s TERM $pid
fi

for i in 1 2 3 4 5
do
    if pmlc $pid </dev/null 2>&1 | grep -E "Connection refused|Transport endpoint is not connected" >/dev/null
    then
	# pmlogger has gone away, continue
	#
	break
    else
	# pmlogger still present
	#
	if [ $i = 5 ]
	then
	    echo "Arrgh, pmlogger process ($pid) will not die ... see $seq.full"
	    exit
	else
	    sleep 2
	fi
    fi
done

echo
echo "files:"
for file in *
do
    new=`echo $file | sed -e "s/$MKTEMP/MKTEMP/" -e "s/$host/HOST/"`
    [ "$new" != "$file" ] && mv $file $new
done
LC_COLLATE=POSIX ls
for log in `LC_COLLATE=POSIX ls *.log`
do
    echo
    echo "=== $log ==="
    echo "=== $log ===" >>$seq_full
    _filter $log
    cat $log >>$seq_full
done

rm -rf *
echo
echo "=== absolute folio name ==="
echo "=== absolute folio name ===" >>$seq_full
echo

$here/src/record `pwd`/foo no-2 0 $host localhost $host localhost 2>&1 >$tmp.out &
sleep 10
# see note above
MKTEMP=`ls *.localhost.0 \
        | tee -a $seq_full \
	| awk '{ print length($0),$0 }' \
	| sort -n \
	| sed -e 's/^[0-9][0-9]* //' -e 's/\.localhost\.0//' -e 1q`
echo "MKTEMP=$MKTEMP" >>$seq_full
_build_sed $tmp.out
echo "-- $tmp.sed --" >>$seq_full
cat $tmp.sed >>$seq_full
echo "-- $tmp.out --" >>$seq_full
cat $tmp.out >>$seq_full
_filter $tmp.out
echo
echo "pmlogger processes:"
echo "pmlogger processes:" >>$seq_full
ps $PCP_PS_ALL_FLAGS 2>&1 \
| tee -a $seq_full \
| sed -n \
    -e 1p \
    -e '/check .*-g pmlogger/d' \
    -e '/[p]mlogger.*-x/{
s/ -x [0-9][0-9]*/ -x N/
p
}' \
| _filter_ps \
| tee $tmp.tmp \
| sed -f $tmp.sed \
| LC_COLLATE=POSIX sort
pid=`$PCP_AWK_PROG '{ print $2 }' <$tmp.tmp`
if [ -z "$pid" ]
then
    # oops!
    #
    echo "Arrgh, no pmlogger process found ... see $seq.full"
    exit
else
    echo "pmlogger pid: $pid" >>$seq_full
    $signal -s TERM $pid
fi

for i in 1 2 3 4 5
do
    if pmlc $pid </dev/null 2>&1 | grep -E "Connection refused|Transport endpoint is not connected" >/dev/null
    then
	# pmlogger has gone away, continue
	#
	break
    else
	# pmlogger still present
	#
	if [ $i = 5 ]
	then
	    echo "Arrgh, pmlogger process ($pid) will not die ... see $seq.full"
	    exit
	else
	    sleep 2
	fi
    fi
done

echo
echo "files:"
for file in *
do
    new=`echo $file | sed -e "s/$MKTEMP/MKTEMP/" -e "s/$host/HOST/"`
    [ "$new" != "$file" ] && mv $file $new
done
LC_COLLATE=POSIX ls
for log in `LC_COLLATE=POSIX ls *.log`
do
    echo
    echo "=== $log ==="
    echo "=== $log ===" >>$seq_full
    _filter $log
    cat $log >>$seq_full
done

# success, all done
status=0
exit
